﻿using AutoMapper;
using Castle.MicroKernel.Registration;
using MRSite.AutoMapper.Attributes;
using MRSite.AutoMapper.Extensions;
using MRSite.Common;
using MRSite.Common.Kernels;
using MRSite.Common.Reflection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace MRSite.AutoMapper
{
    public class AutoMapperKernel : BaseKernel
    {

        public AutoMapperKernel(ITypeFinder typeFinder)
        {
            _typeFinder = typeFinder;
        }

        public override void PreInit()
        {
            CtnManager.Regist<IAutoMapperConfiguration, AutoMapperConfiguration>();
        }

        public override void PostInit()
        {
            CreateMappings();
            CtnManager.Container.Register(
                Component.For<ICommonMapper>().ImplementedBy<AutoCommonMapper>().LifestyleTransient()
                );
        }

        private void CreateMappings()
        {
            Action<IMapperConfigurationExpression> actionConfiguration = con =>
            {
                FindMapTypes(con);
                foreach (var item in ConfigurationManager.MapperConfiguration().ConfigActions)
                {
                    item(con);
                }
            };

            var config = new MapperConfiguration(actionConfiguration);
            CtnManager.Container.Register(
                Component.For<IConfigurationProvider>().Instance(config).LifestyleSingleton()
                );
            CtnManager.Container.Register(
                Component.For<IMapper>().Instance(config.CreateMapper()).LifestyleSingleton()
                );
        }

        private void FindMapTypes(IMapperConfigurationExpression con)
        {
            var types = _typeFinder.FindByCondition(type =>
            {
                var typeInfos = type.GetTypeInfo();
                return typeInfos.IsDefined(typeof(AutoMapBothAttribute));
            });


            foreach (var item in types)
            {
                con.CreateAutoAttributeMaps(item);
            }
        }

        private readonly ITypeFinder _typeFinder;
    }
}
